#pragma once 

#include <iostream>
#include <cstring>
#include <string>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>

#define DEFAULT 8081

class UdpServer{
  private:
    int sockfd;
    int port;
    std::string ip;
  public:
    UdpServer(std::string _ip, int _port = DEFAULT):sockfd(-1), port(_port), ip(_ip)
    {}
    bool InitUdpServer()
    {
      sockfd = socket(AF_INET, SOCK_DGRAM, 0);
      if(sockfd == -1){
        std::cerr << "sockfd error" << std::endl;
      }

      //申请套接字成功，绑定网络数据
      struct sockaddr_in local;
      bzero(&local, sizeof(local));
      //协议家族
      local.sin_family = AF_INET;
      //将端口号转化成网络字节序(大端)
      local.sin_port = htons(port);
      //将string类的ip转化成char类型，然后在转化成四字节类型
      local.sin_addr.s_addr = inet_addr(ip.c_str());
      socklen_t len = sizeof(local);
      if(bind(sockfd, (struct sockaddr*)&local, len) == -1){
        std::cerr << "bind fail" << std::endl;
        return false;
      }

      std::cout << "bind succeed, sockfd->" << sockfd << std::endl;
      return true;
    }
    void Start()
    {
#define SIZE 128
      char buffer[SIZE];
      std::string msg;

      struct sockaddr_in peer;
      socklen_t len = sizeof(peer);
      while(true){
        //读取完成
          //ssize_t size = read(sockfd, buffer, sizeof(buffer) - 1);
          ssize_t size = recvfrom(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&peer, &len);
          if(size == -1){
            std::cerr << "recvfrom error" << std::endl;
          }
          else if(size == 0){
            break;
          }
          else{
            buffer[size] = 0;
            std::cout << "Client send->" << buffer << std::endl;
            //write(sockfd, buffer, sizeof(buffer) - 1);
            sendto(sockfd, buffer, sizeof(buffer) - 1, 0, (struct sockaddr*)&peer, len);
          }
      }
    }
    ~UdpServer()
    {
      if(sockfd != -1) close(sockfd);
    }
};
